feat: add unenroll_learners management command for bulk unenrollment#3603
Conversation
OpenAPI ChangesShow/hide ## Changes for v0.yaml:Unexpected changes? Ensure your branch is up-to-date with |
df36094 to
163556a
Compare
|
Chiming in briefly on this - not sure if it's ready for review yet or not since tests are failing. But there's two things that I think would be helpful:
A potential third:
I did read through the code and it looked pretty good but I haven't done a formal review at the moment. |
|
@jkachel, thanks for the suggestions. I’ve implemented all three of them, and this PR is now ready for review. |
jkachel
left a comment
There was a problem hiding this comment.
LGTM 👍 - one thing to change, which is just moving a test into another folder; as long as it still runs/passes without further changes (which it should), doing this shouldn't require a re-review. Otherwise looks good and works well.
| @@ -0,0 +1,473 @@ | |||
| """Tests for unenroll_learners management command""" | |||
There was a problem hiding this comment.
Nit: move this to courses/management/tests - otherwise, this shows up as a runnable management command.
0676056 to
a1c0042
Compare
What are the relevant tickets?
https://github.com/mitodl/hq/issues/11347
Description
Add a new
unenroll_learnersmanagement command that supports bulk unenrollment of learners from course runs in both edX and MITx Online.Input modes:
--csv— CSV file withuserandcourseware_idcolumns--userswith--run— Comma-separated user emails/usernames for a specific course run--runalone — Unenroll ALL active learners from a course runSafety & options:
--committo execute--no-emailsuppresses unenrollment notification emails-kkeeps local enrollment records even if edX unenrollment failsThe core unenrollment logic is extracted into shared utility functions (
unenroll_learner_from_runandbulk_unenroll_learners) incourses/management/utils.py, which handle user/run resolution, enrollment deactivation viadeactivate_run_enrollment, and structured logging. Asend_notificationparameter was added todeactivate_run_enrollmentincourses/api.pyto support email suppression.The previous single-user
unenroll_enrollmentcommand has been removed sinceunenroll_learnerscovers both single and bulk use cases.How to test
1. Dry-run (default — no changes made):
Verify output shows
(DRY RUN), lists "Would unenroll" entries, and prints "Re-run with --commit to apply changes."2. Unenroll all active learners from a course run (preview):
Verify it lists ALL active enrollments for that run in dry-run mode.
3. Unenroll specific users with --commit:
Verify users are unenrolled from both edX and MITx Online, and summary shows succeeded count.
4. Unenroll via CSV with --commit:
CSV format:
user,courseware_idcolumns. Verify all listed users are unenrolled.5. Unenroll all active learners from a run with --commit:
Verify ALL active enrollments for that run are unenrolled.
6. Suppress unenrollment emails (--no-email):
Verify unenrollment succeeds and no notification email is sent to the learner.
7. Keep failed enrollments (-k):
Verify local enrollment record is preserved even if edX API call fails.
8. Conflicting arguments are rejected:
Verify each raises a clear error message.
9. Run automated tests:
All 26 tests should pass.
Additional Context